#include "Combination.h"
#include <stdlib.h>
#include <cstring>

Combinations::Combinations(const int n, const int k) : n(n), k(k)
{
  c = (int*)malloc(k * sizeof(int));

  //Compute number of combinations
  unsigned long int n2, k2;

  if(n == 0 || k > n)
    comb_total = 0;
  else if(k == 0 || k == n)
    comb_total = 1;
  else
  {
    for(comb_total = 1, k2 = k, n2 = n; k2 > 0; k2--, n2--)
      comb_total *= n2/k2;
  }

  reset();
}

Combinations::~Combinations()
{
  free(c);  
}

void Combinations::reset () 
{
	for(int i = 0; i < k; i++) 
  {
	 c[i] = i;
	}
	comb_remaining = comb_total;
}

bool Combinations::nextCombination(int *comb) 
{
	if(comb_remaining != comb_total) 
  {
	  int i = k - 1;
	  while (c[i] == n - k + i) 
    {
	   i--;
	  }

	  c[i] = c[i] + 1;

	  for (int j = i + 1; j < k; j++) 
    {
	   c[j] = c[i] + j - i;
	  }
  }

  comb_remaining--;
  
  memcpy(comb, c, k*sizeof(int));

  if(comb_remaining == 0)
  {
    reset();
    return false;
  }
  else
    return true;
}

unsigned long int Combinations::numCombinations()
{
  return comb_total;
}

unsigned long int Combinations::remainingCombinations()
{
  return comb_remaining;
}

